#include "HFFAudioPlayer.h"
#include "XResample.h"
#include "XAudioPlay.h"
#include "hlog.h"
#include "hscope.h"
#define PCM_BUF_SIZE 1024 * 1024 * 10

extern "C"
{
#include<libavcodec/avcodec.h>
}

HFFAudioPlayer::HFFAudioPlayer(int sampleRate,int channels):HFFAudioPlayer()
{
    m_audioPlay->sampleRate = sampleRate;
    m_audioPlay->channels = channels;
}

HFFAudioPlayer::HFFAudioPlayer()
{
    isAudio = true;
    m_resample = new XResample();
    m_audioPlay = XAudioPlay::Get();

    m_pcm_buf = (unsigned char *)malloc(PCM_BUF_SIZE);
    if(m_pcm_buf == NULL)
    {
        hloge("malloc fail");
    }
    HThread::setSleepPolicy(HThread::SLEEP_FOR, 1); 
}

HFFAudioPlayer::~HFFAudioPlayer()
{
    hlogi("HFFVideoPlayer::~HFFAudioPlayer()");
    if(m_pcm_buf != NULL)
    {
        free(m_pcm_buf);
        m_pcm_buf = NULL;
    }

    if(m_audioPlay != NULL)
    {
        m_audioPlay->Close();
        m_audioPlay = NULL;
    }
}


void HFFAudioPlayer::doTask()
{
    AVPacket *pkt = Pop();
    if(pkt == NULL)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
        return ;
    }
	bool re = Send(pkt);
	if (!re)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(1));
		return ;
	}

    //一次send 多次recv
	while (!isExit)
	{
		AVFrame * frame = Recv();
		if (!frame) break;
        pts = pts - m_audioPlay->GetNoPlayMs();

        //重采样 
        if(m_pcm_buf == NULL)
        {
            hloge("m_pcm_buf is null");
	        av_frame_free(&frame);
            break;
        }
        memset(m_pcm_buf, 0, PCM_BUF_SIZE);
		int size = m_resample->Resample(frame, m_pcm_buf);

        //播放音频
        while (!isExit)
        {
            if (size <= 0)break;
            //缓冲未播完，空间不够
            if (m_audioPlay->GetFree() > 0)
            {
                std::this_thread::sleep_for(std::chrono::microseconds(100));
                continue;
            }
            m_audioPlay->Write(m_pcm_buf, size);
            break;
        }
	}
}


 int HFFAudioPlayer::pause()
 {
    m_audioPlay->pause();
    return HThread::pause();
 }


int HFFAudioPlayer::resume()
{
    m_audioPlay->resume();
    return HThread::resume();
}
    
    
bool HFFAudioPlayer::Open()
{
    if(!para) return false;   
    
    bool re = true;
    if(!m_resample->Open(para, false))
    {
        hloge("XResample open failed!");
        re = false;
    }

    if(!m_audioPlay->Open())
    {
        re = false;
        hloge("XAudioPlay open failed!");
    }

    if(!HFFDecodeThread::Open())
    {
        hloge("audio XDecode open failed!");
        re = false;
    }

    if(re) 
    {
        hlogi("XAudioThread::Open : true");
    }
    else
    {
        hlogi("XAudioThread::Open : false");
    }

    return re;
}

    
void HFFAudioPlayer::Close()
{
    HFFDecodeThread::Close();

    if(m_audioPlay)
    {
        m_audioPlay->Close();
    }

    if(m_resample)
    {
        m_resample->Close();
        delete m_resample;
        m_resample = NULL;
    }
}

bool HFFAudioPlayer::doPrepare()
{
    bool ret = true;
    ret = Open();
    return ret;
}


bool HFFAudioPlayer::doFinish()
{
    Close();
    return true;
}